package cn.jbolt.core.para;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.io.FileUtil;
import cn.jbolt.core.common.enums.ImageType;
import cn.jbolt.core.util.JBoltArrayUtil;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.CPI;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.upload.UploadFile;

import java.io.File;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

/**
 * JBolt里参数校验工具类
 *
 * @ClassName: JBoltParaValidator
 * @author: JFinal学院-小木 QQ：909854136
 * @date: 2019年12月10日
 */
public class JBoltParaValidator {
	/**
	 * 判断record不是null 并且数据不为空
	 * @param record
	 * @return
	 */
	public static boolean isOk(Record record){
		return notNull(record)&&isOk(record.getColumns());
	}
	/**
	 * 判断record是null 或者数据为空
	 * @param record
	 * @return
	 */
	public static boolean notOk(Record record){
		return isNull(record) || notOk(record.getColumns());
	}
	/**
	 * 判断model不是null 并且数据不为空
	 * @param model
	 * @return
	 */
	public static boolean isOk(Model<? extends Model<?>> model){
		return notNull(model) && isOk(CPI.getAttrs(model));
	}
	/**
	 * 判断model是null 或者数据为空
	 * @param model
	 * @return
	 */
	public static boolean notOk(Model<? extends Model<?>> model){
		return isNull(model) || notOk(CPI.getAttrs(model));
	}
	/**
	 * 判断obj是null
	 * @param obj
	 * @return
	 */
	public static boolean isNull(Object obj){
		return obj == null;
	}
	/**
	 * 判断obj不是null
	 * @param obj
	 * @return
	 */
	public static boolean notNull(Object obj){
		return obj != null;
	}
	/**
	 * 判断Enum参数有效性
	 *
	 * @param param
	 * @return
	 */
	public static boolean isOk(Enum param) {
		return param != null;
	}
	/**
	 * 判断Integer参数有效性
	 *
	 * @param param
	 * @return
	 */
	public static boolean isOk(Integer param) {
		return param != null && param > 0;
	}

	/**
	 * 判断BigInteger参数有效性
	 *
	 * @param param
	 * @return
	 */
	public static boolean isOk(BigInteger param) {
		return param != null && param.intValue() > 0;
	}

	/**
	 * 判断Integer参数是否无效
	 * @return
	 */
	public static boolean notOk(Integer param) {
		return param == null || param <= 0;
	}


	/**
	 * 判断BigInteger参数是否无效
	 * @return
	 */
	public static boolean notOk(BigInteger param) {
		return param == null || param.intValue() <= 0;
	}

	/**
	 * 存在无效参数
	 * @param params
	 * @return
	 */
	public static boolean hasNotOk(Object... params) {
		if(params == null) {return true;}
		for(Object param:params) {
			if(notOk(param)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 存在有效参数
	 * @param params
	 * @return
	 */
	public static boolean hasOk(Object... params) {
		if(params == null) {return true;}
		for(Object param:params) {
			if(isOk(param)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 判断Collection参数有效性
	 * @param param
	 * @return
	 */
	public static boolean isOk(Collection<?> param) {
		return param != null && param.size() > 0;
	}

	/**
	 * 判断List参数有效性
	 * @param param
	 * @return
	 */
	public static boolean isOk(List<?> param) {
		return param != null && param.size() > 0;
	}

	/**
	 * 判断List参数是否无效
	 * @param param
	 * @return
	 */
	public static boolean notOk(List<?> param) {
		return param == null || param.size() == 0;
	}

	/**
	 * 判断Collection参数是否无效
	 * @param param
	 * @return
	 */
	public static boolean notOk(Collection<?> param) {
		return param == null || param.size() == 0;
	}

	/**
	 * 判断上传文件类型不是图片
	 * @param file
	 * @return
	 */
	public static boolean notImage(UploadFile file) {
		if (file == null) {
			return true;
		}
		return notImage(file.getContentType()) || ImageType.notImage(FileTypeUtil.getType(file.getFile()));
	}

	/**
	 * 判断上传文件类型是否为图片
	 * @param file
	 * @return
	 */
	public static boolean isImage(UploadFile file) {
		if (file == null) {
			return false;
		}
		return isImage(file.getContentType()) && ImageType.isImage(FileTypeUtil.getType(file.getFile()));
	}

	/**
	 * 判断String参数是否有效
	 * @param param
	 * @return
	 */
	public static boolean isOk(String param) {
		return StrKit.notBlank(param);
	}

	/**
	 * 判断String参数无效
	 * @param param
	 * @return
	 */
	public static boolean notOk(String param) {
		return StrKit.isBlank(param);
	}

	/**
	 * 判断Double参数是否有效
	 * @param param
	 * @return
	 */
	public static boolean isOk(Double param) {
		return param != null && param > 0;
	}

	/**
	 * 判断Double参数无效
	 * @param param
	 * @return
	 */
	public static boolean notOk(Double param) {
		return param == null || param <= 0;
	}

	/**
	 * 判断Float参数是否有效
	 * @param param
	 * @return
	 */
	public static boolean isOk(Float param) {
		return param != null && param > 0;
	}

	/**
	 * 判断Float参数无效
	 * @param param
	 * @return
	 */
	public static boolean notOk(Float param) {
		return param == null || param <= 0;
	}

	/**
	 * 判断Long参数是否有效
	 * @param param
	 * @return
	 */
	public static boolean isOk(Long param) {
		return param != null && param > 0;
	}

	/**
	 * 判断Long参数无效
	 * @param param
	 * @return
	 */
	public static boolean notOk(Long param) {
		return param == null || param <= 0;
	}

	/**
	 * 判断BigDecimal参数是否有效
	 * @param param
	 * @return
	 */
	public static boolean isOk(BigDecimal param) {
		return param != null && param.doubleValue() > 0;
	}

	/**
	 * 判断BigDecimal参数无效
	 * @param param
	 * @return
	 */
	public static boolean notOk(BigDecimal param) {
		return param == null || param.doubleValue() <= 0;
	}

	/**
	 * 判断上传文件是图片
	 * @param contentType
	 * @return
	 */
	public static boolean isImage(String contentType) {
		return contentType != null && contentType.contains("image/");
	}

	/**
	 * 判断上传文件不是图片
	 * @param contentType
	 * @return
	 */
	public static boolean notImage(String contentType) {
		return contentType == null || !contentType.contains("image/");
	}

	/**
	 * 判断Object[]数组类型数据是否正确
	 * @param param
	 * @return
	 */
	public static boolean isOk(Object[] param) {
		return JBoltArrayUtil.notEmpty(param);
	}

	/**
	 * 判断Serializable[]数组类型数据是否正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean isOk(Serializable[] param) {
		return JBoltArrayUtil.notEmpty(param);
	}

	/**
	 * 判断Object[]数组类型数据不正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean notOk(Object[] param) {
		return JBoltArrayUtil.isEmpty(param);
	}

	/**
	 * 判断Serializable[]数组类型数据不正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean notOk(Serializable[] param) {
		return JBoltArrayUtil.isEmpty(param);
	}

	/**
	 * 判断Integer[]数组类型数据不正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean notOk(Integer[] param) {
		return JBoltArrayUtil.isEmpty(param);
	}

	/**
	 * 判断Date类型数据是否正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean isOk(Date param) {
		return param != null;
	}

	/**
	 * 判断DateTime类型数据是否正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean isOk(DateTime param) {
		return param != null;
	}

	/**
	 * 判断Date类型数据不正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean notOk(Date param) {
		return param == null;
	}

	/**
	 * 判断DateTime类型数据不正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean notOk(DateTime param) {
		return param == null;
	}
	/**
	 * 判断Enum类型数据不正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean notOk(Enum param) {
		return param == null;
	}
	/**
	 * 判断Boolean类型数据不正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean notOk(Boolean param) {
		return param == null;
	}

	/**
	 * 判断Boolean类型数据是否正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean isOk(Boolean param) {
		return param != null;
	}

	/**
	 * 判断Map类型数据不正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean notOk(Map<?, ?> param) {
		return param == null || param.isEmpty();
	}

	/**
	 * 判断Map类型数据是否正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean isOk(Map<?, ?> param) {
		return param != null && !param.isEmpty();
	}

	/**
	 * 判断Set类型数据不正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean notOk(Set<?> param) {
		return param == null || param.isEmpty();
	}

	/**
	 * 判断Set类型数据是否正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean isOk(Set<?> param) {
		return param != null && !param.isEmpty();
	}

	/**
	 * 判断byte[]类型数据不正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean notOk(byte[] param) {
		return param == null || param.length == 0;
	}

	/**
	 * 判断byte[]类型数据是否正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean isOk(byte[] param) {
		return param != null && param.length > 0;
	}

	/**
	 * 判断参数数据不正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean notOk(Object param) {
		if (param == null) {
			return true;
		}
		String name = param.getClass().getSimpleName();
		boolean success = false;
		switch (name) {
			case "Integer":
				success = notOk((Integer) param);
				break;
			case "BigInteger":
				success = notOk((BigInteger) param);
				break;
			case "String":
				success = notOk(param.toString());
				break;
			case "Long":
				success = notOk((Long) param);
				break;
			case "Double":
				success = notOk((Double) param);
				break;
			case "Float":
				success = notOk((Float) param);
				break;
			case "BigDecimal":
				success = notOk((BigDecimal) param);
				break;
			case "List":
				success = notOk((List<?>) param);
				break;
			case "ArrayList":
				if (param.getClass().getName().equals("java.util.Arrays$ArrayList")) {
					success = notOk((Collection<?>) param);
				} else {
					success = notOk((ArrayList<?>) param);
				}
				break;
			case "Boolean":
				success = notOk((Boolean) param);
				break;
			case "Date":
				success = notOk((Date) param);
				break;
			case "Map":
				success = notOk((Map<?, ?>) param);
				break;
			case "HashMap":
				success = notOk((HashMap<?, ?>) param);
				break;
			case "Set":
				success = notOk((Set<?>) param);
				break;
			case "HashSet":
				success = notOk((HashSet<?>) param);
				break;
			case "byte[]":
				success = notOk((byte[])param);
				break;
			case "Record":
				success = notOk((Record)param);
				break;
			case "Model":
				success = notOk((Model<? extends Model<?>>)param);
				break;
			default:
				if(param instanceof Model) {
					success = notOk((Model<? extends Model<?>>)param);
				}else if(param instanceof Record) {
					success = notOk((Record)param);
				}else if(param instanceof Enum) {
					success = notOk((Enum)param);
				}
				break;
			}
		return success;
	}

	/**
	 * 判断参数数据是否正确
	 *
	 * @param param
	 * @return
	 */
	public static boolean isOk(Object param) {
		if (param == null) {
			return false;
		}
		String simpleName = param.getClass().getSimpleName();
		boolean success = false;
		switch (simpleName) {
			case "Integer":
				success = isOk((Integer) param);
				break;
			case "BigInteger":
				success = isOk((BigInteger) param);
				break;
			case "String":
				success = isOk(param.toString());
				break;
			case "Long":
				success = isOk((Long) param);
				break;
			case "Double":
				success = isOk((Double) param);
				break;
			case "Float":
				success = isOk((Float) param);
				break;
			case "BigDecimal":
				success = isOk((BigDecimal) param);
				break;
			case "List":
				success = isOk((List<?>) param);
				break;
			case "ArrayList":
				if (param.getClass().getName().equals("java.util.Arrays$ArrayList")) {
					success = isOk((Collection<?>) param);
				} else {
					success = isOk((ArrayList<?>) param);
				}
				break;
			case "Boolean":
				success = isOk((Boolean) param);
				break;
			case "Date":
				success = isOk((Date) param);
				break;
			case "DateTime":
				success = isOk((DateTime) param);
				break;
			case "Map":
				success = isOk((Map<?, ?>) param);
				break;
			case "HashMap":
				success = isOk((HashMap<?, ?>) param);
				break;
			case "Set":
				success = isOk((Set<?>) param);
				break;
			case "HashSet":
				success = isOk((HashSet<?>) param);
				break;
			case "byte[]":
				success = isOk((byte[])param);
				break;
			case "Record":
				success = isOk((Record)param);
				break;
			case "Model":
				success = isOk((Model<? extends Model<?>>)param);
				break;
			default:
				if(param instanceof Model) {
					success = isOk((Model<? extends Model<?>>)param);
				}else if(param instanceof Record) {
					success = isOk((Record)param);
				}else if(param instanceof Enum) {
					success = isOk((Enum)param);
				}
				break;
			}
		return success;
	}

	/**
	 * 判断是否为excel文件
	 *
	 * @param file
	 * @return
	 */
	public static boolean isExcel(UploadFile file) {
		if (file == null) {
			return false;
		}
		return isExcel(file.getFile());
	}

	/**
	 * 判断不是excel文件
	 *
	 * @param file
	 * @return
	 */
	public static boolean notExcel(UploadFile file) {
		if (file == null) {
			return true;
		}
		return notExcel(file.getFile());
	}

	/**
	 * 判断是否为excel文件
	 *
	 * @param file
	 * @return
	 */
	public static boolean isExcel(File file) {
		if (file == null || !file.exists()) {
			return false;
		}
		boolean isEndWithXls = FileUtil.pathEndsWith(file, "xls") || FileUtil.pathEndsWith(file, "xlsx");
		if (!isEndWithXls) {
			return false;
		}
		String type = FileTypeUtil.getType(file);
		return "xls".equalsIgnoreCase(type) || "xlsx".equalsIgnoreCase(type);
	}

	/**
	 * 判断不是excel文件
	 *
	 * @param file
	 * @return
	 */
	public static boolean notExcel(File file) {
		if (file == null || !file.exists()) {
			return true;
		}
		boolean notEndWithXls = (!FileUtil.pathEndsWith(file, "xls")
				&& !FileUtil.pathEndsWith(file, "xlsx"));
		if (notEndWithXls) {
			return true;
		}
		String type = FileTypeUtil.getType(file);
		return !"xls".equalsIgnoreCase(type) && !"xlsx".equalsIgnoreCase(type);
	}
}
